package com.cloudfun.campusshare.util;

import com.cloudfun.campusshare.common.exception.AuthenticationException;
import com.cloudfun.campusshare.common.model.Token;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

import static com.cloudfun.campusshare.service.impl.TokenFactoryImpl.DEFAULT_SECRETE;

/**
 * Created by linyangping on 2019/10/21.
 */
@Slf4j
public final class JwtUtils {

    //Sample method to construct a JWT
    public static String createJWT(String issuer, String subject, long ttlMillis, String secret) {

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secret);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        JwtBuilder builder = Jwts.builder()
                .setIssuedAt(now)
                .setSubject(subject)
                .setIssuer(issuer)
                .signWith(signatureAlgorithm, signingKey);

        // 设置过期时间
        if (ttlMillis > 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        return builder.compact();
    }

    public static String parseJWT(String jwt, String secret) throws AuthenticationException {
        String subject;
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(secret))
                    .parseClaimsJws(jwt).getBody();
        } catch (Exception e) {
            if (!StringUtils.equals(secret,DEFAULT_SECRETE)) {
                try {
                    claims = Jwts.parser()
                            .setSigningKey(DatatypeConverter.parseBase64Binary(DEFAULT_SECRETE))
                            .parseClaimsJws(jwt).getBody();
                } catch (Exception ee) {
                    log.error("默认密码解析jwt异常,jwt:{},secret:{},：",jwt,DEFAULT_SECRETE, e);
                    throw new AuthenticationException(e.getMessage());
                }
            } else {
                log.error("用户自定义密码解析jwt异常,jwt:{},secret:{},：",jwt,secret, e);
                throw new AuthenticationException(e.getMessage());
            }
        }
        log.info(claims.toString());

        log.debug("Subject: {}", claims.getSubject());
        log.debug("Issuer: {}", claims.getIssuer());
        log.debug("Expiration: {}", claims.getExpiration());
        log.debug("issueAt: {}", claims.getIssuedAt());

        subject = claims.getSubject();

        return subject;

    }

    public static void main(String[] args) {

        Token token = new Token();
        token.setPubKey("");
        token.setUserId("2c9181d36e45b7eb016e45b91cd60000");

        long ttlMillis = 1440 * 600000;


        try {

            String tokenEncryptStr = TokenUtil.encryptToken(token);
            ;

            String jwtStr = JwtUtils.createJWT("hyperchain", tokenEncryptStr, ttlMillis, "69f4cea63ca50550c7d19a2664c2e304");

            System.out.println(jwtStr);

//            String result = JwtUtils.parseJWT(jwtStr,"69f4cea63ca50550c7d19a2664c2e304");
//
//            System.out.println(result);

        } catch (Exception e) {
            e.printStackTrace();
        }


    }


}
